/**
 *
 */
package pers.vic.test.distributed;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import pers.vic.boot.security.redis.RedisService;
import pers.vic.boot.util.redis.JedisUtil;
import pers.vic.boot.util.thread.CustomThreadFactory;
import redis.clients.jedis.Jedis;

import java.util.concurrent.*;

/**
 *  @description: 测试基于redisson的分布式锁 @see RedissonConfig
 *  @author Vic.xu
 *  @date: 2020年11月16日上午10:51:51
 */
//@Service
public class RedissonLock {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisService redisService;

    public boolean testLock() throws Exception {
        RLock lock = redissonClient.getLock("testLock");
        try {
            //获取锁的最大等待时间是秒，10s
            boolean cacheRes = lock.tryLock(30, 10, TimeUnit.SECONDS);
            if (cacheRes) {
                //todo sth
                return true;
            } else {
                throw new RuntimeException("获取分布式锁失败");
            }
        } finally {
            lock.unlock();
        }
    }

    String code = "code";

    public static Long getCode() {
        String key = "abc";
//		redisService.get(code);

        Jedis resource = JedisUtil.getResource();
        Long incr = resource.incrBy(key, 100L);
        if (incr == 100) {
            resource.expire(key, 60);
        }
        return incr;
    }

    public static void main(String[] args) {
        runThread();
    }

    static CountDownLatch countDownLatch = new CountDownLatch(1);

    private static void runThread() {
        ExecutorService executorService = new ThreadPoolExecutor(10, 10,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(100), new CustomThreadFactory("redissonLocak"));
        ;
        for (int i = 0; i < 15; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.await();
                        System.out.println("Thread:" + Thread.currentThread().getName() + ",time: " + System.currentTimeMillis());
                        System.out.println(getCode());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        countDownLatch.countDown();
    }

}
